"""Create database schema

Revision ID: 1c554c77c8e5
Revises: db9c88848f52
Create Date: 2025-07-29 18:41:54.296210

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from pgvector.sqlalchemy import Vector

# revision identifiers, used by Alembic.
revision: str = '1c554c77c8e5'
down_revision: Union[str, None] = 'db9c88848f52'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    """Upgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table('api_key',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('key', sa.String(length=64), nullable=False),
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('description', sa.String(length=256), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('is_system', sa.Boolean(), nullable=False),
    sa.Column('last_used_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_api_key_gmt_deleted'), 'api_key', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_api_key_is_system'), 'api_key', ['is_system'], unique=False)
    op.create_index(op.f('ix_api_key_status'), 'api_key', ['status'], unique=False)
    op.create_index(op.f('ix_api_key_user'), 'api_key', ['user'], unique=False)
    op.create_table('audit_log',
    sa.Column('id', sa.String(length=36), nullable=False),
    sa.Column('user_id', sa.String(length=36), nullable=True, comment='User ID'),
    sa.Column('username', sa.String(length=255), nullable=True, comment='Username'),
    sa.Column('resource_type', sa.String(length=50), nullable=True, comment='Resource type'),
    sa.Column('resource_id', sa.String(length=255), nullable=True, comment='Resource ID (extracted at query time)'),
    sa.Column('api_name', sa.String(length=255), nullable=False, comment='API operation name'),
    sa.Column('http_method', sa.String(length=10), nullable=False, comment='HTTP method (POST, PUT, DELETE)'),
    sa.Column('path', sa.String(length=512), nullable=False, comment='API path'),
    sa.Column('status_code', sa.Integer(), nullable=True, comment='HTTP status code'),
    sa.Column('request_data', sa.Text(), nullable=True, comment='Request data (JSON)'),
    sa.Column('response_data', sa.Text(), nullable=True, comment='Response data (JSON)'),
    sa.Column('error_message', sa.Text(), nullable=True, comment='Error message if failed'),
    sa.Column('ip_address', sa.String(length=45), nullable=True, comment='Client IP address'),
    sa.Column('user_agent', sa.String(length=500), nullable=True, comment='User agent string'),
    sa.Column('request_id', sa.String(length=255), nullable=False, comment='Request ID for tracking'),
    sa.Column('start_time', sa.BigInteger(), nullable=False, comment='Request start time (milliseconds since epoch)'),
    sa.Column('end_time', sa.BigInteger(), nullable=True, comment='Request end time (milliseconds since epoch)'),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False, comment='Created time'),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_audit_api_name', 'audit_log', ['api_name'], unique=False)
    op.create_index('idx_audit_gmt_created', 'audit_log', ['gmt_created'], unique=False)
    op.create_index('idx_audit_http_method', 'audit_log', ['http_method'], unique=False)
    op.create_index('idx_audit_request_id', 'audit_log', ['request_id'], unique=False)
    op.create_index('idx_audit_resource_id', 'audit_log', ['resource_id'], unique=False)
    op.create_index('idx_audit_resource_type', 'audit_log', ['resource_type'], unique=False)
    op.create_index('idx_audit_start_time', 'audit_log', ['start_time'], unique=False)
    op.create_index('idx_audit_status_code', 'audit_log', ['status_code'], unique=False)
    op.create_index('idx_audit_user_id', 'audit_log', ['user_id'], unique=False)
    op.create_table('bot',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('title', sa.String(length=256), nullable=True),
    sa.Column('type', sa.String(length=50), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('config', sa.Text(), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_bot_gmt_deleted'), 'bot', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_bot_status'), 'bot', ['status'], unique=False)
    op.create_index(op.f('ix_bot_user'), 'bot', ['user'], unique=False)
    op.create_table('bot_collection_relation',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('bot_id', sa.String(length=24), nullable=False),
    sa.Column('collection_id', sa.String(length=24), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('bot_id', 'collection_id', 'gmt_deleted', name='uq_bot_collection_deleted')
    )
    op.create_table('chat',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('peer_type', sa.String(length=50), nullable=False),
    sa.Column('peer_id', sa.String(length=256), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('bot_id', sa.String(length=24), nullable=False),
    sa.Column('title', sa.String(length=256), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('bot_id', 'peer_type', 'peer_id', 'gmt_deleted', name='uq_chat_bot_peer_deleted')
    )
    op.create_index(op.f('ix_chat_bot_id'), 'chat', ['bot_id'], unique=False)
    op.create_index(op.f('ix_chat_gmt_deleted'), 'chat', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_chat_status'), 'chat', ['status'], unique=False)
    op.create_index(op.f('ix_chat_user'), 'chat', ['user'], unique=False)
    op.create_table('collection',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('title', sa.String(length=256), nullable=False),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('type', sa.String(length=50), nullable=False),
    sa.Column('config', sa.Text(), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_collection_gmt_deleted'), 'collection', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_collection_status'), 'collection', ['status'], unique=False)
    op.create_index(op.f('ix_collection_user'), 'collection', ['user'], unique=False)
    op.create_table('collection_summary',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('collection_id', sa.String(length=24), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('version', sa.Integer(), nullable=False),
    sa.Column('observed_version', sa.Integer(), nullable=False),
    sa.Column('summary', sa.Text(), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_last_reconciled', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('collection_id', name='uq_collection_summary')
    )
    op.create_index(op.f('ix_collection_summary_collection_id'), 'collection_summary', ['collection_id'], unique=False)
    op.create_index(op.f('ix_collection_summary_status'), 'collection_summary', ['status'], unique=False)
    op.create_table('config',
    sa.Column('key', sa.String(length=256), nullable=False),
    sa.Column('value', sa.Text(), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('key')
    )
    op.create_table('document',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('name', sa.String(length=1024), nullable=False),
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('collection_id', sa.String(length=24), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('size', sa.BigInteger(), nullable=False),
    sa.Column('object_path', sa.Text(), nullable=True),
    sa.Column('doc_metadata', sa.Text(), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('collection_id', 'name', 'gmt_deleted', name='uq_document_collection_name_deleted')
    )
    op.create_index(op.f('ix_document_collection_id'), 'document', ['collection_id'], unique=False)
    op.create_index(op.f('ix_document_gmt_deleted'), 'document', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_document_status'), 'document', ['status'], unique=False)
    op.create_index(op.f('ix_document_user'), 'document', ['user'], unique=False)
    op.create_table('document_index',
    sa.Column('id', sa.Integer(), nullable=False),
    sa.Column('document_id', sa.String(length=24), nullable=False),
    sa.Column('index_type', sa.String(length=50), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('version', sa.Integer(), nullable=False),
    sa.Column('observed_version', sa.Integer(), nullable=False),
    sa.Column('index_data', sa.Text(), nullable=True),
    sa.Column('error_message', sa.Text(), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_last_reconciled', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('document_id', 'index_type', name='uq_document_index')
    )
    op.create_index(op.f('ix_document_index_document_id'), 'document_index', ['document_id'], unique=False)
    op.create_index(op.f('ix_document_index_id'), 'document_index', ['id'], unique=False)
    op.create_index(op.f('ix_document_index_index_type'), 'document_index', ['index_type'], unique=False)
    op.create_index(op.f('ix_document_index_status'), 'document_index', ['status'], unique=False)
    op.create_table('graph_index_merge_suggestions',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('collection_id', sa.String(length=24), nullable=False),
    sa.Column('suggestion_batch_id', sa.String(length=24), nullable=False),
    sa.Column('entity_ids', sa.ARRAY(sa.String()), nullable=False),
    sa.Column('entity_ids_hash', sa.String(length=64), nullable=False),
    sa.Column('confidence_score', sa.Numeric(precision=3, scale=2), nullable=False),
    sa.Column('merge_reason', sa.Text(), nullable=False),
    sa.Column('suggested_target_entity', sa.JSON(), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('collection_id', 'entity_ids_hash', name='uq_graph_index_merge_suggestions')
    )
    op.create_index('idx_graph_index_merge_suggestions_batch', 'graph_index_merge_suggestions', ['collection_id', 'suggestion_batch_id'], unique=False)
    op.create_index('idx_graph_index_merge_suggestions_collection', 'graph_index_merge_suggestions', ['collection_id'], unique=False)
    op.create_index('idx_graph_index_merge_suggestions_confidence', 'graph_index_merge_suggestions', ['confidence_score'], unique=False)
    op.create_index('idx_graph_index_merge_suggestions_created', 'graph_index_merge_suggestions', ['gmt_created'], unique=False)
    op.create_index(op.f('ix_graph_index_merge_suggestions_collection_id'), 'graph_index_merge_suggestions', ['collection_id'], unique=False)
    op.create_index(op.f('ix_graph_index_merge_suggestions_status'), 'graph_index_merge_suggestions', ['status'], unique=False)
    op.create_index(op.f('ix_graph_index_merge_suggestions_suggestion_batch_id'), 'graph_index_merge_suggestions', ['suggestion_batch_id'], unique=False)
    op.create_table('graph_index_merge_suggestions_history',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('original_suggestion_id', sa.String(length=24), nullable=False),
    sa.Column('collection_id', sa.String(length=24), nullable=False),
    sa.Column('suggestion_batch_id', sa.String(length=24), nullable=False),
    sa.Column('entity_ids', sa.ARRAY(sa.String()), nullable=False),
    sa.Column('entity_ids_hash', sa.String(length=64), nullable=False),
    sa.Column('confidence_score', sa.Numeric(precision=3, scale=2), nullable=False),
    sa.Column('merge_reason', sa.Text(), nullable=False),
    sa.Column('suggested_target_entity', sa.JSON(), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('operated_at', sa.DateTime(timezone=True), nullable=False),
    sa.Column('operated_by', sa.String(length=24), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index('idx_graph_index_merge_suggestions_history_batch', 'graph_index_merge_suggestions_history', ['suggestion_batch_id'], unique=False)
    op.create_index('idx_graph_index_merge_suggestions_history_collection', 'graph_index_merge_suggestions_history', ['collection_id'], unique=False)
    op.create_index('idx_graph_index_merge_suggestions_history_collection_status', 'graph_index_merge_suggestions_history', ['collection_id', 'status'], unique=False)
    op.create_index('idx_graph_index_merge_suggestions_history_operated_at', 'graph_index_merge_suggestions_history', ['operated_at'], unique=False)
    op.create_index('idx_graph_index_merge_suggestions_history_original_id', 'graph_index_merge_suggestions_history', ['original_suggestion_id'], unique=False)
    op.create_index(op.f('ix_graph_index_merge_suggestions_history_collection_id'), 'graph_index_merge_suggestions_history', ['collection_id'], unique=False)
    op.create_index(op.f('ix_graph_index_merge_suggestions_history_original_suggestion_id'), 'graph_index_merge_suggestions_history', ['original_suggestion_id'], unique=False)
    op.create_index(op.f('ix_graph_index_merge_suggestions_history_status'), 'graph_index_merge_suggestions_history', ['status'], unique=False)
    op.create_index(op.f('ix_graph_index_merge_suggestions_history_suggestion_batch_id'), 'graph_index_merge_suggestions_history', ['suggestion_batch_id'], unique=False)
    op.create_table('invitation',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('email', sa.String(length=254), nullable=False),
    sa.Column('token', sa.String(length=64), nullable=False),
    sa.Column('created_by', sa.String(length=256), nullable=False),
    sa.Column('created_at', sa.DateTime(timezone=True), nullable=False),
    sa.Column('expires_at', sa.DateTime(timezone=True), nullable=False),
    sa.Column('is_used', sa.Boolean(), nullable=False),
    sa.Column('used_at', sa.DateTime(timezone=True), nullable=True),
    sa.Column('role', sa.String(length=50), nullable=False),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('token')
    )
    op.create_table('lightrag_doc_chunks',
    sa.Column('id', sa.String(length=255), nullable=False),
    sa.Column('workspace', sa.String(length=255), nullable=False),
    sa.Column('full_doc_id', sa.String(length=256), nullable=True),
    sa.Column('chunk_order_index', sa.Integer(), nullable=True),
    sa.Column('tokens', sa.Integer(), nullable=True),
    sa.Column('content', sa.Text(), nullable=True),
    sa.Column('content_vector', Vector(), nullable=True),
    sa.Column('file_path', sa.String(length=256), nullable=True),
    sa.Column('create_time', sa.DateTime(timezone=True), nullable=False),
    sa.Column('update_time', sa.DateTime(timezone=True), nullable=False),
    sa.PrimaryKeyConstraint('id', 'workspace')
    )
    op.create_table('lightrag_graph_edges',
    sa.Column('id', sa.BigInteger(), autoincrement=True, nullable=False),
    sa.Column('source_entity_id', sa.String(length=255), nullable=False),
    sa.Column('target_entity_id', sa.String(length=255), nullable=False),
    sa.Column('weight', sa.Numeric(precision=10, scale=6), nullable=False),
    sa.Column('keywords', sa.Text(), nullable=True),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('source_id', sa.Text(), nullable=True),
    sa.Column('file_path', sa.Text(), nullable=True),
    sa.Column('workspace', sa.String(length=255), nullable=False),
    sa.Column('createtime', sa.DateTime(timezone=True), nullable=False),
    sa.Column('updatetime', sa.DateTime(timezone=True), nullable=False),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('workspace', 'source_entity_id', 'target_entity_id', name='uq_lightrag_graph_edges_workspace_source_target')
    )
    op.create_index('idx_lightrag_edges_degree_calc', 'lightrag_graph_edges', ['workspace', 'source_entity_id', 'target_entity_id', 'weight'], unique=False)
    op.create_index('idx_lightrag_edges_metadata', 'lightrag_graph_edges', ['workspace', 'source_entity_id', 'target_entity_id', 'weight', 'keywords'], unique=False)
    op.create_index('idx_lightrag_edges_weight', 'lightrag_graph_edges', ['workspace', 'weight'], unique=False)
    op.create_index('idx_lightrag_edges_workspace_createtime', 'lightrag_graph_edges', ['workspace', 'createtime'], unique=False)
    op.create_index('idx_lightrag_edges_workspace_source', 'lightrag_graph_edges', ['workspace', 'source_entity_id'], unique=False)
    op.create_index('idx_lightrag_edges_workspace_source_target', 'lightrag_graph_edges', ['workspace', 'source_entity_id', 'target_entity_id'], unique=False)
    op.create_index('idx_lightrag_edges_workspace_target', 'lightrag_graph_edges', ['workspace', 'target_entity_id'], unique=False)
    op.create_index('idx_lightrag_edges_workspace_target_source', 'lightrag_graph_edges', ['workspace', 'target_entity_id', 'source_entity_id'], unique=False)
    op.create_table('lightrag_graph_nodes',
    sa.Column('id', sa.BigInteger(), autoincrement=True, nullable=False),
    sa.Column('entity_id', sa.String(length=256), nullable=False),
    sa.Column('entity_name', sa.String(length=255), nullable=True),
    sa.Column('entity_type', sa.String(length=255), nullable=True),
    sa.Column('description', sa.Text(), nullable=True),
    sa.Column('source_id', sa.Text(), nullable=True),
    sa.Column('file_path', sa.Text(), nullable=True),
    sa.Column('workspace', sa.String(length=255), nullable=False),
    sa.Column('createtime', sa.DateTime(timezone=True), nullable=False),
    sa.Column('updatetime', sa.DateTime(timezone=True), nullable=False),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('workspace', 'entity_id', name='uq_lightrag_graph_nodes_workspace_entity')
    )
    op.create_index('idx_lightrag_nodes_entity_name', 'lightrag_graph_nodes', ['workspace', 'entity_name'], unique=False)
    op.create_index('idx_lightrag_nodes_entity_type', 'lightrag_graph_nodes', ['workspace', 'entity_type'], unique=False)
    op.create_index('idx_lightrag_nodes_entity_type_createtime', 'lightrag_graph_nodes', ['workspace', 'entity_type', 'createtime'], unique=False)
    op.create_index('idx_lightrag_nodes_workspace_createtime', 'lightrag_graph_nodes', ['workspace', 'createtime'], unique=False)
    op.create_index('idx_lightrag_nodes_workspace_type_id', 'lightrag_graph_nodes', ['workspace', 'entity_type', 'entity_id'], unique=False)
    op.create_table('lightrag_vdb_entity',
    sa.Column('id', sa.String(length=255), nullable=False),
    sa.Column('workspace', sa.String(length=255), nullable=False),
    sa.Column('entity_name', sa.String(length=255), nullable=True),
    sa.Column('content', sa.Text(), nullable=True),
    sa.Column('content_vector', Vector(), nullable=True),
    sa.Column('create_time', sa.DateTime(timezone=True), nullable=False),
    sa.Column('update_time', sa.DateTime(timezone=True), nullable=False),
    sa.Column('chunk_ids', sa.ARRAY(sa.String()), nullable=True),
    sa.Column('file_path', sa.Text(), nullable=True),
    sa.PrimaryKeyConstraint('id', 'workspace')
    )
    op.create_table('lightrag_vdb_relation',
    sa.Column('id', sa.String(length=255), nullable=False),
    sa.Column('workspace', sa.String(length=255), nullable=False),
    sa.Column('source_id', sa.String(length=256), nullable=True),
    sa.Column('target_id', sa.String(length=256), nullable=True),
    sa.Column('content', sa.Text(), nullable=True),
    sa.Column('content_vector', Vector(), nullable=True),
    sa.Column('create_time', sa.DateTime(timezone=True), nullable=False),
    sa.Column('update_time', sa.DateTime(timezone=True), nullable=False),
    sa.Column('chunk_ids', sa.ARRAY(sa.String()), nullable=True),
    sa.Column('file_path', sa.Text(), nullable=True),
    sa.PrimaryKeyConstraint('id', 'workspace')
    )
    op.create_table('llm_provider',
    sa.Column('name', sa.String(length=128), nullable=False),
    sa.Column('user_id', sa.String(length=256), nullable=False),
    sa.Column('label', sa.String(length=256), nullable=False),
    sa.Column('completion_dialect', sa.String(length=64), nullable=False),
    sa.Column('embedding_dialect', sa.String(length=64), nullable=False),
    sa.Column('rerank_dialect', sa.String(length=64), nullable=False),
    sa.Column('allow_custom_base_url', sa.Boolean(), nullable=False),
    sa.Column('base_url', sa.String(length=512), nullable=False),
    sa.Column('extra', sa.Text(), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('name')
    )
    op.create_index(op.f('ix_llm_provider_user_id'), 'llm_provider', ['user_id'], unique=False)
    op.create_table('llm_provider_models',
    sa.Column('provider_name', sa.String(length=128), nullable=False),
    sa.Column('api', sa.String(length=50), nullable=False),
    sa.Column('model', sa.String(length=256), nullable=False),
    sa.Column('custom_llm_provider', sa.String(length=128), nullable=False),
    sa.Column('context_window', sa.Integer(), nullable=True),
    sa.Column('max_input_tokens', sa.Integer(), nullable=True),
    sa.Column('max_output_tokens', sa.Integer(), nullable=True),
    sa.Column('tags', sa.JSON(), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('provider_name', 'api', 'model')
    )
    op.create_table('message_feedback',
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('collection_id', sa.String(length=24), nullable=True),
    sa.Column('chat_id', sa.String(length=24), nullable=False),
    sa.Column('message_id', sa.String(length=256), nullable=False),
    sa.Column('type', sa.String(length=50), nullable=True),
    sa.Column('tag', sa.String(length=50), nullable=True),
    sa.Column('message', sa.Text(), nullable=True),
    sa.Column('question', sa.Text(), nullable=True),
    sa.Column('status', sa.String(length=50), nullable=True),
    sa.Column('original_answer', sa.Text(), nullable=True),
    sa.Column('revised_answer', sa.Text(), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('chat_id', 'message_id'),
    sa.UniqueConstraint('chat_id', 'message_id', 'gmt_deleted', name='uq_feedback_chat_message_deleted')
    )
    op.create_index(op.f('ix_message_feedback_collection_id'), 'message_feedback', ['collection_id'], unique=False)
    op.create_index(op.f('ix_message_feedback_gmt_deleted'), 'message_feedback', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_message_feedback_status'), 'message_feedback', ['status'], unique=False)
    op.create_index(op.f('ix_message_feedback_user'), 'message_feedback', ['user'], unique=False)
    op.create_table('model_service_provider',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('name', sa.String(length=256), nullable=False),
    sa.Column('status', sa.String(length=50), nullable=False),
    sa.Column('api_key', sa.String(length=256), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('name', 'gmt_deleted', name='uq_model_service_provider_name_deleted')
    )
    op.create_index(op.f('ix_model_service_provider_gmt_deleted'), 'model_service_provider', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_model_service_provider_name'), 'model_service_provider', ['name'], unique=False)
    op.create_index(op.f('ix_model_service_provider_status'), 'model_service_provider', ['status'], unique=False)
    op.create_table('searchhistory',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('collection_id', sa.String(length=24), nullable=True),
    sa.Column('query', sa.Text(), nullable=False),
    sa.Column('vector_search', sa.JSON(), nullable=True),
    sa.Column('fulltext_search', sa.JSON(), nullable=True),
    sa.Column('graph_search', sa.JSON(), nullable=True),
    sa.Column('summary_search', sa.JSON(), nullable=True),
    sa.Column('items', sa.JSON(), nullable=True),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id')
    )
    op.create_index(op.f('ix_searchhistory_collection_id'), 'searchhistory', ['collection_id'], unique=False)
    op.create_index(op.f('ix_searchhistory_gmt_deleted'), 'searchhistory', ['gmt_deleted'], unique=False)
    op.create_index(op.f('ix_searchhistory_user'), 'searchhistory', ['user'], unique=False)
    op.create_table('user',
    sa.Column('id', sa.String(length=24), nullable=False),
    sa.Column('username', sa.String(length=256), nullable=False),
    sa.Column('email', sa.String(length=254), nullable=True),
    sa.Column('role', sa.String(length=50), nullable=False),
    sa.Column('hashed_password', sa.String(length=128), nullable=False),
    sa.Column('is_active', sa.Boolean(), nullable=False),
    sa.Column('is_superuser', sa.Boolean(), nullable=False),
    sa.Column('is_verified', sa.Boolean(), nullable=False),
    sa.Column('is_staff', sa.Boolean(), nullable=False),
    sa.Column('date_joined', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('id'),
    sa.UniqueConstraint('email'),
    sa.UniqueConstraint('username')
    )
    op.create_table('user_quota',
    sa.Column('user', sa.String(length=256), nullable=False),
    sa.Column('key', sa.String(length=256), nullable=False),
    sa.Column('value', sa.Integer(), nullable=False),
    sa.Column('gmt_created', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_updated', sa.DateTime(timezone=True), nullable=False),
    sa.Column('gmt_deleted', sa.DateTime(timezone=True), nullable=True),
    sa.PrimaryKeyConstraint('user', 'key')
    )
    # ### end Alembic commands ###


def downgrade() -> None:
    """Downgrade schema."""
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('user_quota')
    op.drop_table('user')
    op.drop_index(op.f('ix_searchhistory_user'), table_name='searchhistory')
    op.drop_index(op.f('ix_searchhistory_gmt_deleted'), table_name='searchhistory')
    op.drop_index(op.f('ix_searchhistory_collection_id'), table_name='searchhistory')
    op.drop_table('searchhistory')
    op.drop_index(op.f('ix_model_service_provider_status'), table_name='model_service_provider')
    op.drop_index(op.f('ix_model_service_provider_name'), table_name='model_service_provider')
    op.drop_index(op.f('ix_model_service_provider_gmt_deleted'), table_name='model_service_provider')
    op.drop_table('model_service_provider')
    op.drop_index(op.f('ix_message_feedback_user'), table_name='message_feedback')
    op.drop_index(op.f('ix_message_feedback_status'), table_name='message_feedback')
    op.drop_index(op.f('ix_message_feedback_gmt_deleted'), table_name='message_feedback')
    op.drop_index(op.f('ix_message_feedback_collection_id'), table_name='message_feedback')
    op.drop_table('message_feedback')
    op.drop_table('llm_provider_models')
    op.drop_index(op.f('ix_llm_provider_user_id'), table_name='llm_provider')
    op.drop_table('llm_provider')
    op.drop_table('lightrag_vdb_relation')
    op.drop_table('lightrag_vdb_entity')
    op.drop_index('idx_lightrag_nodes_workspace_type_id', table_name='lightrag_graph_nodes')
    op.drop_index('idx_lightrag_nodes_workspace_createtime', table_name='lightrag_graph_nodes')
    op.drop_index('idx_lightrag_nodes_entity_type_createtime', table_name='lightrag_graph_nodes')
    op.drop_index('idx_lightrag_nodes_entity_type', table_name='lightrag_graph_nodes')
    op.drop_index('idx_lightrag_nodes_entity_name', table_name='lightrag_graph_nodes')
    op.drop_table('lightrag_graph_nodes')
    op.drop_index('idx_lightrag_edges_workspace_target_source', table_name='lightrag_graph_edges')
    op.drop_index('idx_lightrag_edges_workspace_target', table_name='lightrag_graph_edges')
    op.drop_index('idx_lightrag_edges_workspace_source_target', table_name='lightrag_graph_edges')
    op.drop_index('idx_lightrag_edges_workspace_source', table_name='lightrag_graph_edges')
    op.drop_index('idx_lightrag_edges_workspace_createtime', table_name='lightrag_graph_edges')
    op.drop_index('idx_lightrag_edges_weight', table_name='lightrag_graph_edges')
    op.drop_index('idx_lightrag_edges_metadata', table_name='lightrag_graph_edges')
    op.drop_index('idx_lightrag_edges_degree_calc', table_name='lightrag_graph_edges')
    op.drop_table('lightrag_graph_edges')
    op.drop_table('lightrag_doc_chunks')
    op.drop_table('invitation')
    op.drop_index(op.f('ix_graph_index_merge_suggestions_history_suggestion_batch_id'), table_name='graph_index_merge_suggestions_history')
    op.drop_index(op.f('ix_graph_index_merge_suggestions_history_status'), table_name='graph_index_merge_suggestions_history')
    op.drop_index(op.f('ix_graph_index_merge_suggestions_history_original_suggestion_id'), table_name='graph_index_merge_suggestions_history')
    op.drop_index(op.f('ix_graph_index_merge_suggestions_history_collection_id'), table_name='graph_index_merge_suggestions_history')
    op.drop_index('idx_graph_index_merge_suggestions_history_original_id', table_name='graph_index_merge_suggestions_history')
    op.drop_index('idx_graph_index_merge_suggestions_history_operated_at', table_name='graph_index_merge_suggestions_history')
    op.drop_index('idx_graph_index_merge_suggestions_history_collection_status', table_name='graph_index_merge_suggestions_history')
    op.drop_index('idx_graph_index_merge_suggestions_history_collection', table_name='graph_index_merge_suggestions_history')
    op.drop_index('idx_graph_index_merge_suggestions_history_batch', table_name='graph_index_merge_suggestions_history')
    op.drop_table('graph_index_merge_suggestions_history')
    op.drop_index(op.f('ix_graph_index_merge_suggestions_suggestion_batch_id'), table_name='graph_index_merge_suggestions')
    op.drop_index(op.f('ix_graph_index_merge_suggestions_status'), table_name='graph_index_merge_suggestions')
    op.drop_index(op.f('ix_graph_index_merge_suggestions_collection_id'), table_name='graph_index_merge_suggestions')
    op.drop_index('idx_graph_index_merge_suggestions_created', table_name='graph_index_merge_suggestions')
    op.drop_index('idx_graph_index_merge_suggestions_confidence', table_name='graph_index_merge_suggestions')
    op.drop_index('idx_graph_index_merge_suggestions_collection', table_name='graph_index_merge_suggestions')
    op.drop_index('idx_graph_index_merge_suggestions_batch', table_name='graph_index_merge_suggestions')
    op.drop_table('graph_index_merge_suggestions')
    op.drop_index(op.f('ix_document_index_status'), table_name='document_index')
    op.drop_index(op.f('ix_document_index_index_type'), table_name='document_index')
    op.drop_index(op.f('ix_document_index_id'), table_name='document_index')
    op.drop_index(op.f('ix_document_index_document_id'), table_name='document_index')
    op.drop_table('document_index')
    op.drop_index(op.f('ix_document_user'), table_name='document')
    op.drop_index(op.f('ix_document_status'), table_name='document')
    op.drop_index(op.f('ix_document_gmt_deleted'), table_name='document')
    op.drop_index(op.f('ix_document_collection_id'), table_name='document')
    op.drop_table('document')
    op.drop_table('config')
    op.drop_index(op.f('ix_collection_summary_status'), table_name='collection_summary')
    op.drop_index(op.f('ix_collection_summary_collection_id'), table_name='collection_summary')
    op.drop_table('collection_summary')
    op.drop_index(op.f('ix_collection_user'), table_name='collection')
    op.drop_index(op.f('ix_collection_status'), table_name='collection')
    op.drop_index(op.f('ix_collection_gmt_deleted'), table_name='collection')
    op.drop_table('collection')
    op.drop_index(op.f('ix_chat_user'), table_name='chat')
    op.drop_index(op.f('ix_chat_status'), table_name='chat')
    op.drop_index(op.f('ix_chat_gmt_deleted'), table_name='chat')
    op.drop_index(op.f('ix_chat_bot_id'), table_name='chat')
    op.drop_table('chat')
    op.drop_table('bot_collection_relation')
    op.drop_index(op.f('ix_bot_user'), table_name='bot')
    op.drop_index(op.f('ix_bot_status'), table_name='bot')
    op.drop_index(op.f('ix_bot_gmt_deleted'), table_name='bot')
    op.drop_table('bot')
    op.drop_index('idx_audit_user_id', table_name='audit_log')
    op.drop_index('idx_audit_status_code', table_name='audit_log')
    op.drop_index('idx_audit_start_time', table_name='audit_log')
    op.drop_index('idx_audit_resource_type', table_name='audit_log')
    op.drop_index('idx_audit_resource_id', table_name='audit_log')
    op.drop_index('idx_audit_request_id', table_name='audit_log')
    op.drop_index('idx_audit_http_method', table_name='audit_log')
    op.drop_index('idx_audit_gmt_created', table_name='audit_log')
    op.drop_index('idx_audit_api_name', table_name='audit_log')
    op.drop_table('audit_log')
    op.drop_index(op.f('ix_api_key_user'), table_name='api_key')
    op.drop_index(op.f('ix_api_key_status'), table_name='api_key')
    op.drop_index(op.f('ix_api_key_is_system'), table_name='api_key')
    op.drop_index(op.f('ix_api_key_gmt_deleted'), table_name='api_key')
    op.drop_table('api_key')
    # ### end Alembic commands ###
